package priv.wangy.micro.common.po.valid.validator;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.util.StringUtils;
import priv.wangy.micro.common.po.valid.Uscc;

import java.util.regex.Pattern;

/**
 * @author zhangjq
 * @since 2024-03-06
 */
public class UsccValidator implements ConstraintValidator<Uscc, String> {

    private static final String CHARACTERS = "0123456789ABCDEFGHJKLMNPQRTUWXY";

    private static final Pattern PATTERN = Pattern.compile("^[0123456789ABCDEFGHJKLMNPQRTUWXY]+$");

    private static final int[] WEIGHTS = {1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};

    public static boolean checkUscc(String uscc) {
        if (!StringUtils.hasLength(uscc) || uscc.length() != 18 || !PATTERN.matcher(uscc).matches()) {
            return false;
        }

        int sum = 0;
        for (int i = 0; i < 17; i++) {
            char c = uscc.charAt(i);
            int w = WEIGHTS[i];
            int v = CHARACTERS.indexOf(c);
            sum += w * v;
        }

        char cc = CHARACTERS.charAt((31 - sum % 31) % 31);
        char lc = uscc.charAt(17);
        return cc == lc;
    }

    @Override
    public void initialize(Uscc constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        return checkUscc(value.toUpperCase());
    }
}
